home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #2 / Amiga Plus CD - 1999 - No. 2.iso / System-Boost / Workbench / ToolManager / Source / Prefs / menu.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  12KB  |  387 lines

  1. /*
  2.  * menu.c  V3.1
  3.  *
  4.  * TM Menu object class
  5.  *
  6.  * Copyright (C) 1990-98 Stefan Becker
  7.  *
  8.  * This source code is for educational purposes only. You may study it
  9.  * and copy ideas or algorithms from it for your own projects. It is
  10.  * not allowed to use any of the source codes (in full or in parts)
  11.  * in other programs. Especially it is not allowed to create variants
  12.  * of ToolManager or ToolManager-like programs from this source code.
  13.  *
  14.  */
  15.  
  16. #include "toolmanager.h"
  17.  
  18. /* Local data */
  19. #define PROPCHUNKS 2
  20. static const ULONG PropChunkTable[2 * PROPCHUNKS] = {
  21.  ID_TMMO, ID_DATA,
  22.  ID_TMMO, ID_NAME,
  23. };
  24. static const char *TextTitle;
  25. static const char *HelpExecObject;
  26. static const char *HelpSoundObject;
  27.  
  28.  
  29. /* Menu class instance data */
  30. struct MenuClassData {
  31.  struct AttachData *mcd_ExecObject;
  32.  struct AttachData *mcd_SoundObject;
  33.  Object            *mcd_Active;
  34.  Object            *mcd_ExecDrop;
  35.  Object            *mcd_SoundDrop;
  36. };
  37. #define TYPED_INST_DATA(cl, o) ((struct MenuClassData *) INST_DATA((cl), (o)))
  38.  
  39. /* Menu class method: OM_NEW */
  40. #undef  DEBUGFUNCTION
  41. #define DEBUGFUNCTION MenuClassNew
  42. static ULONG MenuClassNew(Class *cl, Object *obj, struct opSet *ops)
  43. {
  44.  MENU_LOG((LOG1(Tags, "0x%08lx", ops->ops_AttrList),
  45.            PrintTagList(ops->ops_AttrList)))
  46.  
  47.  /* Create object */
  48.  if (obj = (Object *) DoSuperNew(cl, obj,
  49.                                        MUIA_Window_Title, TextTitle,
  50.                                        MUIA_HelpNode,     "MenuWindow",
  51.                                        TMA_Type,          TMOBJTYPE_MENU,
  52.                                        TAG_MORE,          ops->ops_AttrList)) {
  53.   struct MenuClassData *mcd = TYPED_INST_DATA(cl, obj);
  54.  
  55.   /* Initialize instance data */
  56.   mcd->mcd_ExecObject  = NULL;
  57.   mcd->mcd_SoundObject = NULL;
  58.   mcd->mcd_Active      = NULL;
  59.  }
  60.  
  61.  MENU_LOG(LOG1(Result, "0x%08lx", obj))
  62.  
  63.  /* Return pointer to created object */
  64.  return((ULONG) obj);
  65. }
  66.  
  67. /* Menu class method: OM_DISPOSE */
  68. #undef  DEBUGFUNCTION
  69. #define DEBUGFUNCTION MenuClassDispose
  70. static ULONG MenuClassDispose(Class *cl, Object *obj, Msg msg)
  71. {
  72.  struct MenuClassData *mcd = TYPED_INST_DATA(cl, obj);
  73.  
  74.  MENU_LOG(LOG1(Disposing, "0x%08lx", obj))
  75.  
  76.  /* Detach objects */
  77.  if (mcd->mcd_ExecObject)  DoMethod(mcd->mcd_ExecObject->ad_Object,
  78.                                     TMM_Detach, mcd->mcd_ExecObject);
  79.  if (mcd->mcd_SoundObject) DoMethod(mcd->mcd_SoundObject->ad_Object,
  80.                                     TMM_Detach, mcd->mcd_SoundObject);
  81.  
  82.  /* Call SuperClass */
  83.  return(DoSuperMethodA(cl, obj, msg));
  84. }
  85.  
  86. /* Menu class method: TMM_Finish */
  87. #undef  DEBUGFUNCTION
  88. #define DEBUGFUNCTION MenuClassFinish
  89. static ULONG MenuClassFinish(Class *cl, Object *obj, struct TMP_Finish *tmpf)
  90. {
  91.  struct MenuClassData *mcd = TYPED_INST_DATA(cl, obj);
  92.  
  93.  MENU_LOG(LOG1(Type, "%ld", tmpf->tmpf_Type))
  94.  
  95.  /* MUI objects allocated? */
  96.  if (mcd->mcd_Active) {
  97.  
  98.   /* Use or Cancel? */
  99.   if (tmpf->tmpf_Type == TMV_Finish_Use) {
  100.  
  101.    /* Get new attach data */
  102.    mcd->mcd_ExecObject  = GetAttachData(mcd->mcd_ExecDrop,  obj,
  103.                                         mcd->mcd_ExecObject);
  104.    mcd->mcd_SoundObject = GetAttachData(mcd->mcd_SoundDrop, obj,
  105.                                         mcd->mcd_SoundObject);
  106.   }
  107.  
  108.   /* Reset pointer to file name area */
  109.   mcd->mcd_Active = NULL;
  110.  }
  111.  
  112.  /* Call SuperClass */
  113.  return(DoSuperMethodA(cl, obj, (Msg) tmpf));
  114. }
  115.  
  116. /* Menu class method: TMM_Notify */
  117. #undef  DEBUGFUNCTION
  118. #define DEBUGFUNCTION MenuClassNotify
  119. static ULONG MenuClassNotify(Class *cl, Object *obj, struct TMP_Notify *tmpn)
  120. {
  121.  MENU_LOG(LOG1(Type, "0x%08lx", tmpn->tmpn_Data->ad_Object))
  122.  
  123.  /* Object deleted? */
  124.  if (tmpn->tmpn_Data->ad_Object == NULL) {
  125.   struct MenuClassData *mcd = TYPED_INST_DATA(cl, obj);
  126.  
  127.   /* Exec or Sound object? */
  128.   if (mcd->mcd_ExecObject == tmpn->tmpn_Data)
  129.    mcd->mcd_ExecObject  = NULL;
  130.   else
  131.    mcd->mcd_SoundObject = NULL;
  132.  }
  133.  
  134.  /* Return 1 to indicate that the method is implemented */
  135.  return(1);
  136. }
  137.  
  138. /* Menu class method: TMM_Edit */
  139. #undef  DEBUGFUNCTION
  140. #define DEBUGFUNCTION MenuClassEdit
  141. static ULONG MenuClassEdit(Class *cl, Object *obj, struct TMP_Edit *tmpe)
  142. {
  143.  struct MenuClassData *mcd = TYPED_INST_DATA(cl, obj);
  144.  
  145.  /* MUI objects allocated? */
  146.  if (mcd->mcd_Active) {
  147.  
  148.   MENU_LOG(LOG0(Object already active))
  149.  
  150.   /* Yes, forward method to SuperClass */
  151.   DoSuperMethodA(cl, obj, (Msg) tmpe);
  152.  
  153.  /* No, create object edit area */
  154.  } else if (mcd->mcd_Active =
  155.     ColGroup(2),
  156.      Child, Label1(TextGlobalExecObject),
  157.      Child, mcd->mcd_ExecDrop  = NewObject(DropAreaClass->mcc_Class, NULL,
  158.                                           TMA_Type,       TMOBJTYPE_EXEC,
  159.                                           TMA_Attach,     mcd->mcd_ExecObject,
  160.                                           MUIA_ShortHelp, HelpExecObject,
  161.                                           TAG_DONE),
  162.      Child, Label1(TextGlobalSoundObject),
  163.      Child, mcd->mcd_SoundDrop = NewObject(DropAreaClass->mcc_Class, NULL,
  164.                                           TMA_Type,       TMOBJTYPE_SOUND,
  165.                                           TMA_Attach,     mcd->mcd_SoundObject,
  166.                                           MUIA_ShortHelp, HelpSoundObject,
  167.                                           TAG_DONE),
  168.     End) {
  169.  
  170.   MENU_LOG(LOG1(Menu Area, "0x%08lx", mcd->mcd_Active))
  171.  
  172.   /* Forward method to SuperClass */
  173.   if (DoSuperMethod(cl, obj, TMM_Edit, mcd->mcd_Active) == NULL) {
  174.  
  175.    /* SuperClass failed, delete file area again */
  176.    MUI_DisposeObject(mcd->mcd_Active);
  177.    mcd->mcd_Active = NULL;
  178.   }
  179.  }
  180.  
  181.  MENU_LOG(LOG1(Result, "0x%08lx", mcd->mcd_Active))
  182.  
  183.  /* Return pointer to file area object to indicate success */
  184.  return((ULONG) mcd->mcd_Active);
  185. }
  186.  
  187. /* Menu class method: TMM_ParseIFF */
  188. #undef  DEBUGFUNCTION
  189. #define DEBUGFUNCTION MenuClassParseIFF
  190. static ULONG MenuClassParseIFF(Class *cl, Object *obj,
  191.                                struct TMP_ParseIFF *tmppi)
  192. {
  193.  BOOL rc = FALSE;
  194.  
  195.  MENU_LOG(LOG1(Handle, "0x%08lx", tmppi->tmppi_IFFHandle))
  196.  
  197.  /* Initialize IFF parser */
  198.  if ((PropChunks(tmppi->tmppi_IFFHandle, PropChunkTable, PROPCHUNKS) == 0) &&
  199.      (StopOnExit(tmppi->tmppi_IFFHandle, ID_TMMO, ID_FORM) == 0) &&
  200.      (ParseIFF(tmppi->tmppi_IFFHandle, IFFPARSE_SCAN) == IFFERR_EOC)) {
  201.   struct StoredProperty *spname;
  202.  
  203.   MENU_LOG(LOG0(FORM TMMO chunk parsed OK))
  204.  
  205.   /* Check for mandatory NAME property */
  206.   if (spname = FindProp(tmppi->tmppi_IFFHandle, ID_TMMO, ID_NAME)) {
  207.    struct StoredProperty *spdata;
  208.  
  209.    MENU_LOG(LOG2(Name, "%s (0x%08lx)", spname->sp_Data, spname->sp_Data))
  210.  
  211.    /* Check for mandatory DATA property */
  212.    if (spdata = FindProp(tmppi->tmppi_IFFHandle, ID_TMMO, ID_DATA)) {
  213.     struct MenuClassData *mcd = TYPED_INST_DATA(cl, obj);
  214.     struct MenuDATAChunk *mdc = spdata->sp_Data;
  215.  
  216.     MENU_LOG(LOG3(Data, "ID 0x%08lx Menu 0x%08lx Sound 0x%08lx",
  217.                   mdc->mdc_Standard.sdc_ID, mdc->mdc_ExecObject,
  218.                   mdc->mdc_SoundObject))
  219.  
  220.     /* Set new name and ID */
  221.     SetAttrs(obj, TMA_Name, spname->sp_Data,
  222.                   TMA_ID,   mdc->mdc_Standard.sdc_ID,
  223.                   TAG_DONE);
  224.  
  225.     /* Attach objects */
  226.     mcd->mcd_ExecObject  = AttachObject(tmppi->tmppi_Lists[TMOBJTYPE_EXEC],
  227.                                         obj, mdc->mdc_ExecObject);
  228.     mcd->mcd_SoundObject = AttachObject(tmppi->tmppi_Lists[TMOBJTYPE_SOUND],
  229.                                         obj, mdc->mdc_SoundObject);
  230.  
  231.     /* All OK */
  232.     rc = TRUE;
  233.    }
  234.   }
  235.  }
  236.  
  237.  MENU_LOG(LOG1(Result, "%ld", rc))
  238.  
  239.  return(rc);
  240. }
  241.  
  242. /* Menu class method: TMM_WriteIFF */
  243. #undef  DEBUGFUNCTION
  244. #define DEBUGFUNCTION MenuClassWriteIFF
  245. static ULONG MenuClassWriteIFF(Class *cl, Object *obj,
  246.                                struct TMP_WriteIFF *tmpwi)
  247. {
  248.  struct MenuClassData *mcd  = TYPED_INST_DATA(cl, obj);
  249.  struct MenuDATAChunk  mdc;
  250.  BOOL                  rc;
  251.  
  252.  MENU_LOG(LOG1(IFFHandle, "0x%08lx", tmpwi->tmpwi_IFFHandle))
  253.  
  254.  /* Initialize DATA chunk (use object addresses as IDs) */
  255.  mdc.mdc_Standard.sdc_ID    = (ULONG) obj;
  256.  mdc.mdc_Standard.sdc_Flags = 0;
  257.  mdc.mdc_ExecObject         = (ULONG) (mcd->mcd_ExecObject  ?
  258.                                         mcd->mcd_ExecObject->ad_Object  :
  259.                                         NULL);
  260.  mdc.mdc_SoundObject        = (ULONG) (mcd->mcd_SoundObject ?
  261.                                         mcd->mcd_SoundObject->ad_Object :
  262.                                         NULL);
  263.  
  264.  /* a) Forward message to SuperClass first */
  265.  /* b) Push DATA chunk                     */
  266.  rc = DoSuperMethodA(cl, obj, (Msg) tmpwi) &&
  267.       WriteProperty(tmpwi->tmpwi_IFFHandle, ID_DATA, &mdc,
  268.                     sizeof(struct MenuDATAChunk));
  269.  
  270.  MENU_LOG(LOG1(Result, "%ld", rc))
  271.  
  272.  return(rc);
  273. }
  274.  
  275. /* Menu class method: TMM_WBArg */
  276. #undef  DEBUGFUNCTION
  277. #define DEBUGFUNCTION MenuClassWBArg
  278. static ULONG MenuClassWBArg(Class *cl, Object *obj, struct TMP_WBArg *tmpwa)
  279. {
  280.  ULONG rc;
  281.  
  282.  MENU_LOG(LOG1(WBArg, "0x%08lx", tmpwa->tmpwa_Argument))
  283.  
  284.  /* First forward method to SuperClass */
  285.  if (rc = DoSuperMethodA(cl, obj, (Msg) tmpwa)) {
  286.   Object *exec;
  287.  
  288.   MENU_LOG(LOG0(Creating objects))
  289.  
  290.   /* Create exec object from WBArg */
  291.   if (exec = (Object *) DoMethodA(tmpwa->tmpwa_Lists[TMOBJTYPE_EXEC],
  292.                                   (Msg) tmpwa)) {
  293.  
  294.    MENU_LOG(LOG1(Exec, "0x%08lx", exec))
  295.  
  296.    /* Attach new exec object */
  297.    SetAttrs(TYPED_INST_DATA(cl, obj)->mcd_ExecDrop, TMA_Object, exec,
  298.                                                     TAG_DONE);
  299.   }
  300.  }
  301.  
  302.  MENU_LOG(LOG1(Result, "0x%08lx", rc))
  303.  
  304.  return(rc);
  305. }
  306.  
  307. /* Menu class method dispatcher */
  308. #undef  DEBUGFUNCTION
  309. #define DEBUGFUNCTION MenuClassDispatcher
  310. __geta4 static ULONG MenuClassDispatcher(__a0 Class *cl, __a2 Object *obj,
  311.                                          __a1 Msg msg)
  312. {
  313.  ULONG rc;
  314.  
  315.  MENU_LOG(LOG3(Arguments, "Class 0x%08lx Object 0x%08lx Msg 0x%08lx",
  316.                cl, obj, msg))
  317.  
  318.  switch(msg->MethodID) {
  319.   /* BOOPSI methods */
  320.   case OM_NEW:
  321.    rc = MenuClassNew(cl, obj, (struct opSet *) msg);
  322.    break;
  323.  
  324.   case OM_DISPOSE:
  325.    rc = MenuClassDispose(cl, obj, msg);
  326.    break;
  327.  
  328.   /* TM methods */
  329.   case TMM_Finish:
  330.    rc = MenuClassFinish(cl, obj, (struct TMP_Finish *) msg);
  331.    break;
  332.  
  333.   case TMM_Notify:
  334.    rc = MenuClassNotify(cl, obj, (struct TMP_Notify *) msg);
  335.    break;
  336.  
  337.   case TMM_Edit:
  338.    rc = MenuClassEdit(cl, obj, (struct TMP_Edit *) msg);
  339.    break;
  340.  
  341.   case TMM_ParseIFF:
  342.    rc = MenuClassParseIFF(cl, obj, (struct TMP_ParseIFF *) msg);
  343.    break;
  344.  
  345.   case TMM_WriteIFF:
  346.    rc = MenuClassWriteIFF(cl, obj, (struct TMP_WriteIFF *) msg);
  347.    break;
  348.  
  349.   case TMM_WBArg:
  350.    rc = MenuClassWBArg(cl, obj, (struct TMP_WBArg *) msg);
  351.    break;
  352.  
  353.   /* Unknown method -> delegate to SuperClass */
  354.   default:
  355.    rc = DoSuperMethodA(cl, obj, msg);
  356.    break;
  357.  }
  358.  
  359.  return(rc);
  360. }
  361.  
  362. /* Create Menu class */
  363. #undef  DEBUGFUNCTION
  364. #define DEBUGFUNCTION CreateMenuClass
  365. struct MUI_CustomClass *CreateMenuClass(void)
  366. {
  367.  struct MUI_CustomClass *rc;
  368.  
  369.  /* Create class */
  370.  if (rc = MUI_CreateCustomClass(NULL, NULL, BaseClass,
  371.                                 sizeof(struct MenuClassData),
  372.                                 MenuClassDispatcher)) {
  373.  
  374.   /* Localize strings */
  375.   TextTitle       = TranslateString(LOCALE_TEXT_MENU_TITLE_STR,
  376.                                     LOCALE_TEXT_MENU_TITLE);
  377.   HelpExecObject  = TranslateString(LOCALE_HELP_MENU_EXEC_OBJECT_STR,
  378.                                     LOCALE_HELP_MENU_EXEC_OBJECT);
  379.   HelpSoundObject = TranslateString(LOCALE_HELP_MENU_SOUND_OBJECT_STR,
  380.                                     LOCALE_HELP_MENU_SOUND_OBJECT);
  381.  }
  382.  
  383.  MENU_LOG(LOG1(Result, "0x%08lx", rc))
  384.  
  385.  return(rc);
  386. }
  387.